import React, { useRef, useEffect, createRef, forwardRef, useImperativeHandle } from 'react';

// useRef获取dom元素
export default function Demo() {
    const btn = useRef(null);

    useEffect(() => {
        console.log(btn);
    }, [])
    
    return (
        <div>
            <button ref={btn}>按钮</button>
        </div>
    )
}

// createRef获取dom

// createRef每次渲染会返回一个新的引用
// useRef每次都会返回相同的引用
export default function Demo() {
    const btn = createRef(null);

    useEffect(() => {
        console.log(btn);
    }, [])
    
    return (
        <div>
            <button ref={btn}>按钮</button>
        </div>
    )
}

// 如果子组件是个类组件，我们为其设置ref，获取到的是子组件的实例。拿到实例以后可以调用子组件上提供的属性和方法
// 如果子组件是个函数组件，会报错，函数组件不能设置ref
export default function Demo() {
    const box = useRef(null);

    useEffect(() => {

    }, [])

    return (
        <div>
            <Child ref={box}></Child>
        </div>
    )
}

// 解决办法，ref获取函数子组件
// forwardRef   useImperativeHandle
// ref 转发
const Child = forwardRef(function Child(props, ref){
    const submit = () => {

    };

    useImperativeHandle(ref, () => {
        // 这里的return的对象，在父组件中box.current能拿到
        return {
            submit
        }
    });

    return (
        // ref可以把div这个dom赋值给父组件的box.current
        <div ref={ref}> 
            <button>提交</button>
        </div>
    )
});

export default function Demo() {
    const box = useRef(null);

    return (
        <div>
            <Child ref={box}></Child>
        </div>
    )
}